"""
PDF图片导入工具
支持PDF查看、旋转、导出为图片
"""

import tkinter as tk
from tkinter import ttk, filedialog, messagebox, simpledialog
import os
import sys
from pathlib import Path
import threading
import io

try:
    import fitz  # PyMuPDF
except ImportError:
    messagebox.showerror("错误", "请先安装PyMuPDF库：pip install PyMuPDF")
    sys.exit(1)

try:
    from PIL import Image, ImageTk
except ImportError:
    messagebox.showerror("错误", "请先安装Pillow库：pip install Pillow")
    sys.exit(1)


class PDFViewerConverter:
    """PDF查看器和转换器主类"""

    def __init__(self, root):
        self.root = root
        self.root.title("PDF查看器和转换器")
        self.root.geometry("1200x800")
        self.root.minsize(800, 600)

        # PDF相关变量
        self.pdf_document = None
        self.current_page = 0
        self.total_pages = 0
        self.page_rotations = {}  # 存储每页的旋转角度
        self.zoom_level = 1.0
        self.current_pdf_path = None

        # 设置变量
        self.dpi_var = tk.IntVar(value=150)
        self.format_var = tk.StringVar(value="PNG")
        self.quality_var = tk.IntVar(value=95)

        self.setup_ui()
        self.setup_menu()

    def setup_menu(self):
        """设置菜单栏"""
        menubar = tk.Menu(self.root)
        self.root.config(menu=menubar)

        # 文件菜单
        file_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="文件", menu=file_menu)
        file_menu.add_command(label="打开PDF...", command=self.open_pdf, accelerator="Ctrl+O")
        file_menu.add_separator()
        file_menu.add_command(label="导出当前页", command=self.export_current_page, accelerator="Ctrl+E")
        file_menu.add_command(label="导出所有页面", command=self.export_all_pages, accelerator="Ctrl+Shift+E")
        file_menu.add_separator()
        file_menu.add_command(label="退出", command=self.root.quit, accelerator="Ctrl+Q")

        # 查看菜单
        view_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="查看", menu=view_menu)
        view_menu.add_command(label="放大", command=self.zoom_in, accelerator="Ctrl++")
        view_menu.add_command(label="缩小", command=self.zoom_out, accelerator="Ctrl+-")
        view_menu.add_command(label="适合窗口", command=self.fit_to_window, accelerator="Ctrl+0")
        view_menu.add_separator()
        view_menu.add_command(label="顺时针旋转", command=self.rotate_clockwise, accelerator="Ctrl+R")
        view_menu.add_command(label="逆时针旋转", command=self.rotate_counterclockwise, accelerator="Ctrl+Shift+R")

        # 设置菜单
        settings_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="设置", menu=settings_menu)
        settings_menu.add_command(label="导出设置", command=self.show_settings_dialog)

        # 帮助菜单
        help_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="帮助", menu=help_menu)
        help_menu.add_command(label="快捷键", command=self.show_shortcuts)
        help_menu.add_command(label="关于", command=self.show_about)

        # 绑定快捷键
        self.root.bind('<Control-o>', lambda e: self.open_pdf())
        self.root.bind('<Control-e>', lambda e: self.export_current_page())
        self.root.bind('<Control-Shift-E>', lambda e: self.export_all_pages())
        self.root.bind('<Control-q>', lambda e: self.root.quit())
        self.root.bind('<Control-plus>', lambda e: self.zoom_in())
        self.root.bind('<Control-minus>', lambda e: self.zoom_out())
        self.root.bind('<Control-0>', lambda e: self.fit_to_window())
        self.root.bind('<Control-r>', lambda e: self.rotate_clockwise())
        self.root.bind('<Control-Shift-R>', lambda e: self.rotate_counterclockwise())

    def setup_ui(self):
        """设置用户界面"""
        # 主框架
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        # 顶部工具栏
        self.setup_toolbar(main_frame)

        # 中间内容区域
        content_frame = ttk.Frame(main_frame)
        content_frame.pack(fill=tk.BOTH, expand=True, pady=(5, 0))

        # PDF显示区域（左侧）
        self.setup_pdf_display(content_frame)

        # 控制面板（右侧）
        self.setup_control_panel(content_frame)

        # 底部状态栏
        self.setup_status_bar(main_frame)

    def setup_toolbar(self, parent):
        """设置工具栏"""
        toolbar = ttk.Frame(parent)
        toolbar.pack(fill=tk.X, pady=(0, 5))

        # 文件操作按钮
        ttk.Button(toolbar, text="打开PDF", command=self.open_pdf, width=12).pack(side=tk.LEFT, padx=(0, 5))

        ttk.Separator(toolbar, orient=tk.VERTICAL).pack(side=tk.LEFT, fill=tk.Y, padx=5)

        # 页面导航
        ttk.Button(toolbar, text="◀", command=self.prev_page, width=3).pack(side=tk.LEFT, padx=(0, 2))
        ttk.Button(toolbar, text="▶", command=self.next_page, width=3).pack(side=tk.LEFT, padx=(0, 5))

        # 页面信息
        self.page_info_label = ttk.Label(toolbar, text="0 / 0")
        self.page_info_label.pack(side=tk.LEFT, padx=(0, 10))

        ttk.Separator(toolbar, orient=tk.VERTICAL).pack(side=tk.LEFT, fill=tk.Y, padx=5)

        # 缩放控制
        ttk.Label(toolbar, text="缩放:").pack(side=tk.LEFT, padx=(0, 2))
        ttk.Button(toolbar, text="−", command=self.zoom_out, width=3).pack(side=tk.LEFT, padx=(0, 2))

        self.zoom_label = ttk.Label(toolbar, text="100%", width=6)
        self.zoom_label.pack(side=tk.LEFT, padx=(0, 2))

        ttk.Button(toolbar, text="+", command=self.zoom_in, width=3).pack(side=tk.LEFT, padx=(0, 2))
        ttk.Button(toolbar, text="适合", command=self.fit_to_window, width=6).pack(side=tk.LEFT, padx=(0, 10))

        ttk.Separator(toolbar, orient=tk.VERTICAL).pack(side=tk.LEFT, fill=tk.Y, padx=5)

        # 旋转按钮
        ttk.Button(toolbar, text="↻", command=self.rotate_counterclockwise, width=3).pack(side=tk.LEFT, padx=(0, 2))
        ttk.Button(toolbar, text="↺", command=self.rotate_clockwise, width=3).pack(side=tk.LEFT, padx=(0, 10))

        ttk.Separator(toolbar, orient=tk.VERTICAL).pack(side=tk.LEFT, fill=tk.Y, padx=5)

        # 导出按钮
        ttk.Button(toolbar, text="导出当前页", command=self.export_current_page).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(toolbar, text="导出所有页", command=self.export_all_pages).pack(side=tk.LEFT)

    def setup_pdf_display(self, parent):
        """设置PDF显示区域"""
        # PDF显示框架
        pdf_frame = ttk.LabelFrame(parent, text="PDF预览")
        pdf_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 5))

        # 创建Canvas和滚动条
        canvas_frame = ttk.Frame(pdf_frame)
        canvas_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        self.canvas = tk.Canvas(canvas_frame, bg='white')

        # 滚动条
        v_scrollbar = ttk.Scrollbar(canvas_frame, orient=tk.VERTICAL, command=self.canvas.yview)
        h_scrollbar = ttk.Scrollbar(canvas_frame, orient=tk.HORIZONTAL, command=self.canvas.xview)

        self.canvas.configure(yscrollcommand=v_scrollbar.set, xscrollcommand=h_scrollbar.set)

        # 布局
        self.canvas.grid(row=0, column=0, sticky="nsew")
        v_scrollbar.grid(row=0, column=1, sticky="ns")
        h_scrollbar.grid(row=1, column=0, sticky="ew")

        canvas_frame.grid_rowconfigure(0, weight=1)
        canvas_frame.grid_columnconfigure(0, weight=1)

        # 鼠标滚轮绑定
        self.canvas.bind("<MouseWheel>", self.on_mousewheel)
        self.canvas.bind("<Button-4>", self.on_mousewheel)
        self.canvas.bind("<Button-5>", self.on_mousewheel)

        # 绑定Canvas大小变化事件，用于更新提示文字位置
        self.canvas.bind("<Configure>", self.on_canvas_configure)

        # 显示提示文本（初始位置，会在on_canvas_configure中更新）
        self.placeholder_text = self.canvas.create_text(400, 300, text="请打开PDF文件", font=("Arial", 16), fill="gray")

    def on_canvas_configure(self, event):
        """Canvas大小变化时的回调函数"""
        if self.placeholder_text and self.canvas.find_all():
            # 更新提示文字到Canvas中心
            canvas_width = event.width
            canvas_height = event.height
            self.canvas.coords(self.placeholder_text, canvas_width // 2, canvas_height // 2)

    def setup_control_panel(self, parent):
        """设置控制面板"""
        control_frame = ttk.LabelFrame(parent, text="控制面板")
        control_frame.pack(side=tk.RIGHT, fill=tk.Y, padx=(5, 0))
        control_frame.configure(width=250)
        control_frame.pack_propagate(False)

        # 文件信息
        info_frame = ttk.LabelFrame(control_frame, text="文件信息")
        info_frame.pack(fill=tk.X, padx=5, pady=5)

        self.file_info_text = tk.Text(info_frame, height=4, wrap=tk.WORD)
        self.file_info_text.pack(fill=tk.X, padx=5, pady=5)

        # 页面导航
        nav_frame = ttk.LabelFrame(control_frame, text="页面导航")
        nav_frame.pack(fill=tk.X, padx=5, pady=5)

        nav_buttons_frame = ttk.Frame(nav_frame)
        nav_buttons_frame.pack(fill=tk.X, padx=5, pady=5)

        # 修复：设置统一的按钮宽度，确保按钮在同一行且不被挤走
        ttk.Button(nav_buttons_frame, text="首页", command=self.goto_first_page, width=6).pack(side=tk.LEFT, padx=(0, 1))
        ttk.Button(nav_buttons_frame, text="上一页", command=self.prev_page, width=6).pack(side=tk.LEFT, padx=1)
        ttk.Button(nav_buttons_frame, text="下一页", command=self.next_page, width=6).pack(side=tk.LEFT, padx=1)
        ttk.Button(nav_buttons_frame, text="末页", command=self.goto_last_page, width=6).pack(side=tk.LEFT, padx=(1, 0))

        # 跳转到指定页面
        goto_frame = ttk.Frame(nav_frame)
        goto_frame.pack(fill=tk.X, padx=5, pady=(0, 5))

        ttk.Label(goto_frame, text="跳转到:").pack(side=tk.LEFT)
        self.page_entry = ttk.Entry(goto_frame, width=8)
        self.page_entry.pack(side=tk.LEFT, padx=(5, 2))
        ttk.Button(goto_frame, text="确定", command=self.goto_page).pack(side=tk.LEFT)

        self.page_entry.bind('<Return>', lambda e: self.goto_page())

        # 导出设置
        export_frame = ttk.LabelFrame(control_frame, text="导出设置")
        export_frame.pack(fill=tk.X, padx=5, pady=5)

        # DPI设置
        dpi_frame = ttk.Frame(export_frame)
        dpi_frame.pack(fill=tk.X, padx=5, pady=2)
        ttk.Label(dpi_frame, text="DPI:").pack(side=tk.LEFT)
        dpi_combo = ttk.Combobox(dpi_frame, textvariable=self.dpi_var, values=[72, 96, 150, 200, 300, 600], width=8)
        dpi_combo.pack(side=tk.RIGHT)

        # 格式设置
        format_frame = ttk.Frame(export_frame)
        format_frame.pack(fill=tk.X, padx=5, pady=2)
        ttk.Label(format_frame, text="格式:").pack(side=tk.LEFT)
        format_combo = ttk.Combobox(format_frame, textvariable=self.format_var,
                                    values=["PNG", "JPG", "JPEG", "BMP", "TIFF"], width=8)
        format_combo.pack(side=tk.RIGHT)

        # 质量设置（仅JPG）
        quality_frame = ttk.Frame(export_frame)
        quality_frame.pack(fill=tk.X, padx=5, pady=2)
        ttk.Label(quality_frame, text="质量:").pack(side=tk.LEFT)
        quality_scale = ttk.Scale(quality_frame, from_=10, to=100, variable=self.quality_var, orient=tk.HORIZONTAL)
        quality_scale.pack(side=tk.RIGHT, fill=tk.X, expand=True)

        # 质量显示
        self.quality_label = ttk.Label(export_frame, text="95%")
        self.quality_label.pack(pady=2)
        quality_scale.configure(command=self.update_quality_label)

        # 快速导出按钮
        export_buttons_frame = ttk.Frame(export_frame)
        export_buttons_frame.pack(fill=tk.X, padx=5, pady=5)

        ttk.Button(export_buttons_frame, text="导出当前页", command=self.export_current_page).pack(fill=tk.X,
                                                                                                   pady=(0, 2))
        ttk.Button(export_buttons_frame, text="导出所有页面", command=self.export_all_pages).pack(fill=tk.X)

    def setup_status_bar(self, parent):
        """设置状态栏"""
        self.status_bar = ttk.Label(parent, text="就绪", relief=tk.SUNKEN, anchor=tk.W)
        self.status_bar.pack(side=tk.BOTTOM, fill=tk.X, pady=(5, 0))

    def update_quality_label(self, value):
        """更新质量标签"""
        self.quality_label.config(text=f"{int(float(value))}%")

    def update_status(self, message):
        """更新状态栏"""
        self.status_bar.config(text=message)
        self.root.update_idletasks()

    def open_pdf(self):
        """打开PDF文件"""
        file_path = filedialog.askopenfilename(
            title="选择PDF文件",
            filetypes=[("PDF文件", "*.pdf"), ("所有文件", "*.*")]
        )

        if file_path:
            try:
                self.update_status("正在加载PDF...")

                # 关闭之前的文档
                if self.pdf_document:
                    self.pdf_document.close()

                # 打开新文档
                self.pdf_document = fitz.open(file_path)
                self.current_pdf_path = file_path
                self.total_pages = len(self.pdf_document)
                self.current_page = 0
                self.page_rotations.clear()

                # 更新文件信息
                self.update_file_info()

                # 显示第一页
                self.display_current_page()

                # 更新UI状态
                self.update_page_info()
                self.update_status(f"已加载PDF: {os.path.basename(file_path)}")

            except Exception as e:
                messagebox.showerror("错误", f"无法打开PDF文件: {str(e)}")
                self.update_status("打开文件失败")

    def update_file_info(self):
        """更新文件信息显示"""
        if not self.pdf_document:
            return

        info_text = f"文件: {os.path.basename(self.current_pdf_path)}\n"
        info_text += f"页数: {self.total_pages}\n"

        # 获取元数据
        metadata = self.pdf_document.metadata
        if metadata.get('title'):
            info_text += f"标题: {metadata['title'][:30]}\n"
        if metadata.get('author'):
            info_text += f"作者: {metadata['author'][:30]}\n"

        self.file_info_text.delete(1.0, tk.END)
        self.file_info_text.insert(1.0, info_text)

    def display_current_page(self):
        """显示当前页面"""
        if not self.pdf_document or self.current_page >= self.total_pages:
            return

        try:
            # 删除提示文字
            if self.placeholder_text:
                self.canvas.delete(self.placeholder_text)
                self.placeholder_text = None

            # 获取页面
            page = self.pdf_document.load_page(self.current_page)

            # 应用旋转
            rotation = self.page_rotations.get(self.current_page, 0)

            # 设置缩放和旋转矩阵
            zoom = self.zoom_level
            mat = fitz.Matrix(zoom, zoom).prerotate(rotation)

            # 渲染页面
            pix = page.get_pixmap(matrix=mat)

            # 转换为PIL图像
            img_data = pix.tobytes("ppm")
            img = Image.open(io.BytesIO(img_data))

            # 转换为PhotoImage
            self.current_image = ImageTk.PhotoImage(img)

            # 清除Canvas并显示图像
            self.canvas.delete("all")

            # 计算居中位置
            canvas_width = self.canvas.winfo_width()
            canvas_height = self.canvas.winfo_height()
            img_width, img_height = img.size

            x = max(0, (canvas_width - img_width) // 2)
            y = max(0, (canvas_height - img_height) // 2)

            self.canvas.create_image(x, y, anchor=tk.NW, image=self.current_image)

            # 更新滚动区域
            self.canvas.configure(scrollregion=self.canvas.bbox("all"))

        except Exception as e:
            messagebox.showerror("错误", f"无法显示页面: {str(e)}")

    def update_page_info(self):
        """更新页面信息"""
        if self.pdf_document:
            self.page_info_label.config(text=f"{self.current_page + 1} / {self.total_pages}")
            self.page_entry.delete(0, tk.END)
            self.page_entry.insert(0, str(self.current_page + 1))
        else:
            self.page_info_label.config(text="0 / 0")

    def prev_page(self):
        """上一页"""
        if self.pdf_document and self.current_page > 0:
            self.current_page -= 1
            self.display_current_page()
            self.update_page_info()

    def next_page(self):
        """下一页"""
        if self.pdf_document and self.current_page < self.total_pages - 1:
            self.current_page += 1
            self.display_current_page()
            self.update_page_info()

    def goto_first_page(self):
        """跳转到首页"""
        if self.pdf_document:
            self.current_page = 0
            self.display_current_page()
            self.update_page_info()

    def goto_last_page(self):
        """跳转到末页"""
        if self.pdf_document:
            self.current_page = self.total_pages - 1
            self.display_current_page()
            self.update_page_info()

    def goto_page(self):
        """跳转到指定页面"""
        if not self.pdf_document:
            return

        try:
            page_num = int(self.page_entry.get()) - 1
            if 0 <= page_num < self.total_pages:
                self.current_page = page_num
                self.display_current_page()
                self.update_page_info()
            else:
                messagebox.showerror("错误", f"页面号必须在1到{self.total_pages}之间")
        except ValueError:
            messagebox.showerror("错误", "请输入有效的页面号")

    def zoom_in(self):
        """放大"""
        self.zoom_level = min(self.zoom_level * 1.2, 5.0)
        self.update_zoom_label()
        self.display_current_page()

    def zoom_out(self):
        """缩小"""
        self.zoom_level = max(self.zoom_level / 1.2, 0.1)
        self.update_zoom_label()
        self.display_current_page()

    def fit_to_window(self):
        """适合窗口"""
        if not self.pdf_document:
            return

        try:
            page = self.pdf_document.load_page(self.current_page)
            page_rect = page.rect

            canvas_width = self.canvas.winfo_width()
            canvas_height = self.canvas.winfo_height()

            # 计算合适的缩放比例
            width_ratio = canvas_width / page_rect.width
            height_ratio = canvas_height / page_rect.height
            self.zoom_level = min(width_ratio, height_ratio) * 0.9  # 留一些边距

            self.update_zoom_label()
            self.display_current_page()

        except Exception as e:
            messagebox.showerror("错误", f"无法适合窗口: {str(e)}")

    def update_zoom_label(self):
        """更新缩放标签"""
        self.zoom_label.config(text=f"{int(self.zoom_level * 100)}%")

    def rotate_clockwise(self):
        """顺时针旋转"""
        if self.pdf_document:
            current_rotation = self.page_rotations.get(self.current_page, 0)
            self.page_rotations[self.current_page] = (current_rotation + 90) % 360
            self.display_current_page()

    def rotate_counterclockwise(self):
        """逆时针旋转"""
        if self.pdf_document:
            current_rotation = self.page_rotations.get(self.current_page, 0)
            self.page_rotations[self.current_page] = (current_rotation - 90) % 360
            self.display_current_page()

    def export_current_page(self):
        """导出当前页面"""
        if not self.pdf_document:
            messagebox.showwarning("警告", "请先打开PDF文件")
            return

        # 选择保存位置
        default_name = f"{Path(self.current_pdf_path).stem}_page_{self.current_page + 1}.{self.format_var.get().lower()}"
        file_path = filedialog.asksaveasfilename(
            title="保存图片",
            defaultextension=f".{self.format_var.get().lower()}",
            initialvalue=default_name,
            filetypes=[
                (f"{self.format_var.get()}文件", f"*.{self.format_var.get().lower()}"),
                ("所有文件", "*.*")
            ]
        )

        if file_path:
            try:
                self.update_status("正在导出...")
                self._export_page(self.current_page, file_path)
                self.update_status(f"已导出: {os.path.basename(file_path)}")
                messagebox.showinfo("成功", f"页面已成功导出到:\n{file_path}")
            except Exception as e:
                messagebox.showerror("错误", f"导出失败: {str(e)}")
                self.update_status("导出失败")

    def export_all_pages(self):
        """导出所有页面"""
        if not self.pdf_document:
            messagebox.showwarning("警告", "请先打开PDF文件")
            return

        # 选择保存目录
        output_dir = filedialog.askdirectory(title="选择导出目录")
        if not output_dir:
            return

        # 确认导出
        result = messagebox.askyesno(
            "确认导出",
            f"将导出所有{self.total_pages}页到指定目录。\n继续吗？"
        )
        if not result:
            return

        # 创建进度窗口
        progress_window = tk.Toplevel(self.root)
        progress_window.title("导出进度")
        progress_window.geometry("400x150")
        progress_window.resizable(False, False)
        progress_window.transient(self.root)
        progress_window.grab_set()

        # 进度条
        progress_label = ttk.Label(progress_window, text="准备导出...")
        progress_label.pack(pady=10)

        progress_bar = ttk.Progressbar(progress_window, length=350, mode='determinate')
        progress_bar.pack(pady=10)
        progress_bar['maximum'] = self.total_pages

        cancel_button = ttk.Button(progress_window, text="取消")
        cancel_button.pack(pady=10)

        # 导出状态
        self.export_cancelled = False
        cancel_button.configure(command=lambda: setattr(self, 'export_cancelled', True))

        def export_thread():
            """导出线程"""
            success_count = 0
            failed_count = 0

            try:
                for page_num in range(self.total_pages):
                    if self.export_cancelled:
                        break

                    # 更新进度
                    self.root.after(0, lambda p=page_num: progress_label.config(text=f"正在导出第 {p + 1} 页..."))
                    self.root.after(0, lambda: progress_bar.step(1))

                    try:
                        # 生成文件名
                        filename = f"{Path(self.current_pdf_path).stem}_page_{page_num + 1:03d}.{self.format_var.get().lower()}"
                        file_path = os.path.join(output_dir, filename)

                        # 导出页面
                        self._export_page(page_num, file_path)
                        success_count += 1

                    except Exception as e:
                        print(f"导出第{page_num + 1}页失败: {e}")
                        failed_count += 1

            finally:
                # 关闭进度窗口
                self.root.after(0, progress_window.destroy)

                # 显示结果
                if not self.export_cancelled:
                    message = f"导出完成!\n成功: {success_count} 页\n失败: {failed_count} 页"
                    self.root.after(0, lambda: messagebox.showinfo("导出完成", message))
                    self.root.after(0, lambda: self.update_status(f"批量导出完成: {success_count}/{self.total_pages}"))
                else:
                    self.root.after(0, lambda: self.update_status("导出已取消"))

        # 启动导出线程
        threading.Thread(target=export_thread, daemon=True).start()

    def _export_page(self, page_num, file_path):
        """导出单个页面的内部方法"""
        page = self.pdf_document.load_page(page_num)

        # 应用旋转
        rotation = self.page_rotations.get(page_num, 0)

        # 设置DPI和旋转
        zoom = self.dpi_var.get() / 72.0
        mat = fitz.Matrix(zoom, zoom).prerotate(rotation)

        # 渲染页面
        pix = page.get_pixmap(matrix=mat)

        # 保存图片
        if self.format_var.get().upper() in ['JPG', 'JPEG']:
            # JPG格式需要特殊处理
            img_data = pix.tobytes("ppm")
            img = Image.open(io.BytesIO(img_data))
            img = img.convert('RGB')  # 移除透明通道
            img.save(file_path, 'JPEG', quality=self.quality_var.get())
        else:
            # 其他格式直接保存
            pix.save(file_path)

    def on_mousewheel(self, event):
        """鼠标滚轮事件"""
        if event.delta:
            # Windows
            delta = event.delta / 120
        else:
            # Linux
            delta = -1 if event.num == 5 else 1

        # 检查是否按住Ctrl键（缩放）
        if event.state & 0x4:  # Ctrl键
            if delta > 0:
                self.zoom_in()
            else:
                self.zoom_out()
        else:
            # 正常滚动
            self.canvas.yview_scroll(int(-delta), "units")

    def show_settings_dialog(self):
        """显示设置对话框"""
        settings_window = tk.Toplevel(self.root)
        settings_window.title("导出设置")
        settings_window.geometry("300x200")
        settings_window.resizable(False, False)
        settings_window.transient(self.root)
        settings_window.grab_set()

        # DPI设置
        ttk.Label(settings_window, text="DPI分辨率:").pack(pady=5)
        dpi_frame = ttk.Frame(settings_window)
        dpi_frame.pack(pady=5)
        ttk.Entry(dpi_frame, textvariable=self.dpi_var, width=10).pack(side=tk.LEFT)
        ttk.Label(dpi_frame, text="(72-600)").pack(side=tk.LEFT, padx=(5, 0))

        # 格式设置
        ttk.Label(settings_window, text="图片格式:").pack(pady=(10, 5))
        format_combo = ttk.Combobox(settings_window, textvariable=self.format_var,
                                    values=["PNG", "JPG", "JPEG", "BMP", "TIFF"], width=15)
        format_combo.pack(pady=5)

        # 质量设置
        ttk.Label(settings_window, text="JPG质量:").pack(pady=(10, 5))
        quality_frame = ttk.Frame(settings_window)
        quality_frame.pack(pady=5)
        ttk.Scale(quality_frame, from_=10, to=100, variable=self.quality_var,
                  orient=tk.HORIZONTAL, length=200).pack()

        # 按钮
        button_frame = ttk.Frame(settings_window)
        button_frame.pack(pady=20)
        ttk.Button(button_frame, text="确定", command=settings_window.destroy).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="取消", command=settings_window.destroy).pack(side=tk.LEFT, padx=5)

    def show_shortcuts(self):
        """显示快捷键帮助"""
        shortcuts_text = """快捷键列表:

文件操作:
Ctrl+O - 打开PDF文件
Ctrl+E - 导出当前页
Ctrl+Shift+E - 导出所有页面
Ctrl+Q - 退出程序

查看操作:
Ctrl++ - 放大
Ctrl+- - 缩小  
Ctrl+0 - 适合窗口
Ctrl+R - 顺时针旋转
Ctrl+Shift+R - 逆时针旋转

导航操作:
←/→ - 上一页/下一页
Page Up/Page Down - 翻页
Home/End - 首页/末页

鼠标操作:
滚轮 - 垂直滚动
Ctrl+滚轮 - 缩放"""

        messagebox.showinfo("快捷键", shortcuts_text)

    def show_about(self):
        """显示关于信息"""
        about_text = """PDF查看器和转换器 v1.0

功能特点:
• PDF文件查看
• 页面旋转和缩放
• 导出为多种图片格式
• 批量导出功能
• 直观的图形界面

依赖库:
• PyMuPDF (fitz)
• Pillow (PIL)
• tkinter

作者: JohnnyZhao
"""

        messagebox.showinfo("关于", about_text)


def main():
    """主函数"""
    root = tk.Tk()
    app = PDFViewerConverter(root)

    # 设置应用图标
    try:
        # root.iconbitmap('icon.ico')  # 取消注释并提供图标文件
        pass
    except:
        pass

    root.mainloop()


if __name__ == "__main__":
    main()